package com.gxa.hualian.web.servlet;

import com.gxa.hualian.exception.BusinessException;
import com.gxa.hualian.exception.ExceptionCode;
import com.gxa.hualian.util.JsonResult;
import com.gxa.hualian.util.ResponseUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.SimpleDateFormat;
import java.util.Date;

@WebServlet(name = "ExceptionServlet", value = "/error")
public class ExceptionServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    doPost(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    //当其他Servlet转发请求到达的时候
        //从request作用域中获取Exception异常对象e
        Exception e = (Exception) request.getAttribute("exception");
        //声明JsonResult,封装给前端返回的信息
        JsonResult jsonResult = new JsonResult();
        if( e instanceof BusinessException){
            // 满足条件,表示当前异常是一个自定义的业务异常
            //把e强转为BusinessException
            BusinessException businessException = (BusinessException) e;

            // 给前端一个反馈
            // 50003
            jsonResult.setCode(businessException.getExceptionCode().getCode());
            // 重复的手机号, 通过枚举直接获取
            jsonResult.setMsg(businessException.getExceptionCode().getMessage());
            // 通过异常对象获取
            jsonResult.setMsg(businessException.getMessage());
        }else{
            //也要给前端反馈
            // 50001
            jsonResult.setCode(ExceptionCode.SERVER_FAILED.getCode());
            // 服务器开小差了,请稍后再试
            jsonResult.setMsg(ExceptionCode.SERVER_FAILED.getMessage());
            e.printStackTrace();
            // 表示系统异常(NullPointerException/ClassNotFoundException)
            // 处理: 记录日志
            // 原则: 1. 以天为单位, 当天的异常都放在同一个文件中,追加写入
            // 2. 文件名体现日期
            // 文件的位置的确定: 1. 通过上下文对象获取程序在服务器中的根目录 ,
            //C:\Users\26065\IdeaProjects\javaee268\out\artifacts
            //   2. d:/log/error2021-09-15.log(推荐, Linux中没有盘符,就把路径配置为properties文件)
            // String realPath = this.getServletContext().getRealPath("/");
// 用系统当前日期作为文件名标记
            String path = "d:"+ File.separator+"log"+File.separator;
            String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
            File file = new File(path+"error" + format + ".log");
            // 判断该文件/目录是否存在
            if (!file.exists()) {
                file.createNewFile();
            }
            // 使用文件输出字节流,且用追加方式
            FileOutputStream fileOutputStream = new FileOutputStream(file,true);
            // 利用字节字符流(桥梁流,流的装饰模式)
            OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream,"UTF8");

            //
            // 写入内容
            //---------------------------------------------------------
            // 异常类型:
            // 异常的原因:
            // 异常在栈中的发生轨迹
            // ---------------------------------------------------------
            StringBuilder builder = new StringBuilder();
            builder.append("---------------------------------------------------------\r\n");
            builder.append("异常类型: ").append(e.toString()).append("\r\n");
            builder.append("异常原因: ").append(e.getMessage()).append("\r\n");
            for (StackTraceElement stackTraceElement : e.getStackTrace()) {
                builder.append(stackTraceElement.toString()).append("\r\n");
            }
            builder.append("---------------------------------------------------------\r\n");
            writer.write(builder.toString());
            writer.flush();
            writer.close();


        }
        ResponseUtil responseUtil = new ResponseUtil(response,jsonResult);
        responseUtil.write();
    }
}
